const DB = require('../../config/DB')
const {
    Op
} = require('sequelize')
const ffmpeg = require('fluent-ffmpeg');
const fs = require('fs')

const { join } = require('path')

// const baseUrl = 'http://192.168.78.203:3000'
// const baseUrl = 'http://127.0.0.1:3000'
const baseUrl = `http://${global.config.serve_config.host}:${global.config.serve_config.port}`;
console.log(baseUrl);

// Minio 客户端
const Minio = require('minio');

// MinIO 客户端配置
const minioClient = new Minio.Client({
    endPoint: global.config.minio_config.minio_endpoint,
    port: global.config.minio_config.minio_port,
    useSSL: global.config.minio_config.minio_use_ssl,
    accessKey: global.config.minio_config.minio_access_key,
    secretKey: global.config.minio_config.minio_secret_key
});

class FileController {
    async listTree(ctx) {
        let tree = []

        let dirs = fs.readdirSync('static/upload')

        dirs.forEach((item, index) => {
            let obj = {
                label: item,
                children: []
            }
            let fPath = join('static/upload', item)
            let files = fs.readdirSync(fPath)
            files.forEach(file => {
                obj.children.push({ label: file })
            })

            tree.push(obj)
        })
        global.Response.success(ctx, undefined, tree)
    }


    // 获取文件详情
    async getFile(ctx) {
        const {
            id, name
        } = ctx.query

        let data = ''
        if (id) {
            data = await DB.file.findByPk(id)
        }
        if (name) {
            data = await DB.file.findOne({
                where: {
                    name
                }
            })
        }

        global.Response.success(ctx, undefined, data)
    }


    // 更新文件
    async updateFile(ctx) {
        let {
            id,
            content,
            title,
            url
        } = ctx.request.body

        try {
            let file

            if (id) {
                file = await DB.file.findByPk(id)
            } else if (url) {
                file = await DB.file.findOne({
                    where: {
                        url
                    }
                })
            }

            if (file) {
                // 不更新文件原名
                if (!title) title = file.get('title')

                // 更新文件内容
                if (content) {
                    let fileUrl = file.get('url')
                    fs.writeFileSync(`./static${fileUrl}`, content)
                }

                file.set({
                    updateAt: Moment().format('YYYY-MM-DD HH:mm:ss'),
                    title
                })

                await file.save()
            }


            global.Response.success(ctx, undefined, file)
        } catch (err) {
            console.error(err)
        }
    }

    // 删除文件
    async delFile(ctx) {
        const {
            id,
            url
        } = ctx.query

        if (id) {
            var file = await DB.file.findByPk(id)
            var fileUrl = 'static' + file.get('url')
            var res = await DB.file.destroy({
                where: {
                    id
                }
            })
        } else if (url) {
            var fileUrl = 'static' + url
            var res = await DB.file.destroy({
                where: {
                    url
                }
            })
        }

        if (res) {
            global.utils.uDeleteFile(fileUrl)
            global.Response.success(ctx, '删除成功')

        } else {
            global.Response.null(ctx)
        }
    }

    // 生成文件
    async createFile(ctx) {
        let {
            title,
            content,
            type
        } = ctx.request.body

        try {
            let fileName = Date.now()

            let dirName = global.Moment().format('YYYY-MM-DD')

            let fileDir = `static/upload/${dirName}` //根目录 注意路径必须存在
            global.utils.uMakeDir(fileDir) // 生成日期目录

            fs.writeFileSync(`./static/upload/${dirName}/${fileName}.${type}`, content)

            const params = {
                name: fileName + '.' + type,
                title: title + '.' + type,
                url: '/upload/' + dirName + '/' + fileName + '.' + type,
                type,
                size: '000', // 暂时未解决
                createAt: global.Moment().format('YYYY-MM-DD HH:mm:ss'),
                updateAt: global.Moment().format('YYYY-MM-DD HH:mm:ss')
            }

            const file = await DB.file.create(params)


            global.Response.success(ctx, undefined, file)
        } catch (err) {
            console.error(err)
        }
    }

    // 上传文件
    async uploadFile(ctx) {
        // 所以实际的文件保存流程是：
// 当请求到达 Upload.single('file') 中间件时
// multer 会根据配置的 storage：
// 使用 destination 函数生成目标目录 (static/upload/YYYY-MM-DD/)
// 使用 filename 函数生成文件名
// multer 自动将文件保存到指定位置
// 然后请求才会到达 FileController.uploadFile
// 这就是为什么在 FileController.uploadFile 中我们只能看到文件信息的数据库操作，而看不到实际的文件保存操作 - 因为文件已经被 multer 中间件保存好了。
// 在 FileController.uploadFile 中我们可以通过 ctx.req.file 来获取 multer 保存的文件信息：
        
        // 获取凭证，但是似乎得用cookie获取凭证。
        // const proof = ctx.req.body.proof || ''
        // const user = await DB.user.findOne({
        //     where: {
        //         proof
        //     }
        // })

        // 如果检测不到凭证，则拒绝上传.
        // if (!user) {
        //     global.utils.uDeleteFile(ctx.req.file.destination + `/${ctx.req.file.filename}`)
        //     global.Response.fail(ctx, '上传失败，凭证错误')
        //     return false
        // }

        // // 1. 用户身份验证
        // const userId = ctx.request.body.userId
        // if (!userId) {
        //     global.utils.uDeleteFile(ctx.req.file.destination + `/${ctx.req.file.filename}`)
        //     global.Response.fail(ctx, '上传失败，需要用户ID')
        //     return false
        // }

        // const user = await DB.user.findByPk(userId)
        // if (!user) {
        //     global.utils.uDeleteFile(ctx.req.file.destination + `/${ctx.req.file.filename}`)
        //     global.Response.fail(ctx, '上传失败，用户不存在')
        //     return false
        // }

        // // 2. 文件类型验证
        // const allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'mp4', 'MP4']
        // const fileType = ctx.req.file.filename.substring(ctx.req.file.filename.lastIndexOf('.') + 1)
        
        // if (!allowedTypes.includes(fileType)) {
        //     global.utils.uDeleteFile(ctx.req.file.destination + `/${ctx.req.file.filename}`)
        //     global.Response.fail(ctx, '不支持的文件类型')
        //     return false
        // }

        // // 3. 文件大小验证
        // const maxSize = 1024 * 1024 * 1024 * 4 // 4GB
        // if (ctx.req.file.size > maxSize) {
        //     global.utils.uDeleteFile(ctx.req.file.destination + `/${ctx.req.file.filename}`)
        //     global.Response.fail(ctx, '文件大小超出限制')
        //     return false
        // }

        // // 4. 文件完整性验证
        // if (!ctx.req.file || !ctx.req.file.filename) {
        //     global.Response.fail(ctx, '文件上传失败，请重试')
        //     return false
        // }

        // // 5. 检查存储空间
        // try {
        //     const stats = fs.statSync(ctx.req.file.destination)
        //     const availableSpace = stats.available
        //     if (ctx.req.file.size > availableSpace) {
        //         global.utils.uDeleteFile(ctx.req.file.destination + `/${ctx.req.file.filename}`)
        //         global.Response.fail(ctx, '服务器存储空间不足')
        //         return false
        //     }
        // } catch (err) {
        //     console.error('存储空间检查失败:', err)
        //     global.Response.fail(ctx, '文件系统错误')
        //     return false
        // }

        const params = {
            name: ctx.req.file.filename,
            title: ctx.req.file.originalname, // 原文件名 中文会乱码
            url: (ctx.req.file.destination + `/${ctx.req.file.filename}`).replace('static', ''),
            type: ctx.req.file.filename.substring(ctx.req.file.filename.lastIndexOf('.') + 1), // 文件类型
            size: ctx.req.file.size / (1024 * 1024),
            // userId: user.get('id'),
            createAt: Moment().format('YYYY-MM-DD HH:mm:ss'),
            updateAt: Moment().format('YYYY-MM-DD HH:mm:ss')
        }
        const file = await DB.file.create(params)

        // 设置输入视频文件和输出图片文件
        const videoFileName=ctx.req.file.filename;
        const inputPath = ctx.req.file.destination+'/'+videoFileName;// 你的视频文件路径
        const outputName = videoFileName.replace('.mp4','.jpg').replace('.MP4','.jpg');

        // 使用fluent-ffmpeg来处理视频文件
        ffmpeg(inputPath)
        .on('filenames', function(filenames) {
            console.log('Will generate ' + filenames.join(', '))
        })
        .on('end', function() {
            console.log('Screenshots taken');
        })
        .on('error', function(err) {
            console.error(err);
        })
        // 指定视频中的时间来获取帧，例如2秒处
        .screenshots({
            count: 1,
            folder: ctx.req.file.destination+'/',
            filename: outputName,
            timestamps: ['00:00:02']
        });

        // 添加http前缀
        file.url = baseUrl + file.url

        file.url = baseUrl +(ctx.req.file.destination + `/${outputName}`).replace('static', '')

    
        global.Response.success(ctx, undefined, file)
    }

    // 上传文件至minio - 只负责数据库操作
    async uploadFileMinio(ctx) {
        try {
            const file = ctx.req.file;
            const minioUrl = ctx.state.minioUrl; // 从中间件获取URL
            
            // 保存到数据库
            const params = {
                name: file.filename,
                title: file.originalname,
                // 修改这里：如果是视频文件，使用缩略图URL，否则使用原文件URL
                url: file.filename.toLowerCase().endsWith('.mp4') ? 
                    ctx.state.thumbnailUrl : // 视频文件使用缩略图URL
                    ctx.state.minioUrl,      // 非视频文件使用原文件URL
                type: file.filename.substring(file.filename.lastIndexOf('.') + 1),
                size: file.size / (1024 * 1024),
                createAt: global.Moment().format('YYYY-MM-DD HH:mm:ss'),
                updateAt: global.Moment().format('YYYY-MM-DD HH:mm:ss')
            };
            
            const dbFile = await DB.file.create(params);

            // 如果是视频文件，添加原始视频URL到返回数据中
            if (file.filename.toLowerCase().endsWith('.mp4')) {
                dbFile.dataValues.videoUrl = ctx.state.minioUrl;
            }

            global.Response.success(ctx, undefined, dbFile);
        } catch (error) {
            console.error('Database operation error:', error);
            global.Response.error(ctx, error.message);
        }
    }

    async takePic(ctx)
    {
        // 设置输入视频文件和输出图片文件
        const videoFileName='1729596199088.mp4';
        const inputPath = `static/upload/${global.Moment().format('YYYY-MM-DD')}`+'/'+videoFileName;// 你的视频文件路径
        const outputName = videoFileName.replace('.mp4','.jpg').replace('.MP4','.jpg');

        // 使用fluent-ffmpeg来处理视频文件
        ffmpeg(inputPath)
        .on('filenames', function(filenames) {
            console.log('Will generate ' + filenames.join(', '))
        })
        .on('end', function() {
            console.log('Screenshots taken');
        })
        .on('error', function(err) {
            console.error(err);
        })
        // 指定视频中的时间来获取帧，例如2秒处
        .screenshots({
            count: 1,
            folder: `static/upload/${global.Moment().format('YYYY-MM-DD')}`+'/',
            filename: outputName,
            timestamps: ['00:00:02']
        });

        global.Response.success(ctx, undefined, [])
    }

    // 搜索文件
    async searchFile(ctx) {
        // 参数
        let {
            page = 1, size = 10, key = '' // 关键词
        } = ctx.query

        page = Number(page)
        size = Number(size)

        const {
            count,
            rows
        } = await DB.file.findAndCountAll({
            offset: (page - 1) * size,
            limit: size,
            order: [
                ['id', 'DESC']
            ],
            where: {
                title: {
                    [Op.like]: `%${key}%`
                }
            }
        })

        const data = {
            rows,
            meta: {
                key,
                size, // 每页条目
                count: count, // 条目总数
                page: page, // 当前页数
                total: Math.ceil(count / size), // 总页数
            }
        }
        global.Response.success(ctx, undefined, data)
    }

    // 获取文件列表
    async listFile(ctx) {
        // 参数
        let {
            page = 1, size = 10
        } = ctx.query

        page = Number(page)
        size = Number(size)

        const {
            count,
            rows
        } = await DB.file.findAndCountAll({
            offset: (page - 1) * size,
            limit: size,
            order: [
                ['id', 'DESC']
            ],
        })

        // for (let row of rows) {
        //     const userId = row.get('userId')
        //     if (userId) {
        //         const user = await DB.user.findByPk(userId)
        //         row.dataValues.userName = user.name
        //     }
        // }

        const data = {
            rows,
            meta: {
                size, // 每页条目
                count: count, // 条目总数
                page: page, // 当前页数
                total: Math.ceil(count / size), // 总页数
            }
        }
        global.Response.success(ctx, undefined, data)
    }
}

module.exports = new FileController
